﻿#include "cxmlparser.h"

#include <QFile>
#include <QDomDocument>
#include <QDebug>

/**
    &lt; < 小于号
    &gt; > 大于号
    &amp; & 和
    &apos; ' 单引号
    &quot; " 双引号
*/
QMap<char, QString> CXMLParser::s_escapeCharsMap;

QString CXMLParser::swapEscapeChar(QString string)
{
    QString returnString = string;
    QList<char> keys = s_escapeCharsMap.keys();
    int keysSize = keys.size();
    for(int i = 0; i < keysSize; ++i)
    {
        char key = keys.at(i);
        if (string.contains(key))
        {
            returnString = string.replace(key, s_escapeCharsMap.value(key));
            qDebug() << returnString;
        }
    }
    return  returnString;
}

CXMLParser::CXMLParser()
{


}

void CXMLParser::Init_CXMLParser()
{
    if (s_escapeCharsMap.size() == 0)
    {
        s_escapeCharsMap.insert('<', "&lt;");
        s_escapeCharsMap.insert('>', "&gt;");
        s_escapeCharsMap.insert('&', "&amp;");
        s_escapeCharsMap.insert('\'', "&apos;");
        s_escapeCharsMap.insert('"', "&quot;");
    }
}

stSetting CXMLParser::parseSettingXMLFile(const QString &filePath)
{
    stSetting settingXML;

    // 打开或创建文件
    // 检验是否正常打开
    QFile file(filePath);
    if (!file.open(QFile::ReadOnly))
    {
        // 打开文件失败。
        return settingXML;
    }

    QDomDocument doc;

    // 如果解析失败
    if (!doc.setContent(&file))
    {
        file.close();
        return settingXML;
    }
    file.close();


    // 开始正常解析
    QDomElement setting = doc.documentElement();
    while (! setting.isNull())
    {
        if (setting.isElement())
        {
            QDomElement domelement = setting.toElement();
            QDomNodeList ls = domelement.childNodes();

            for (int i = 0; i < ls.size(); i++)
            {
                // 题目所在的目录
                if(! strcmp(ls.at(i).nodeName().toStdString().c_str(), DIR_BASEQUESLIB.toStdString().c_str()))
                {
                    settingXML.dir_baseQuesLib = ls.at(i).toElement().text();
                }
                // 导出的目录
                else if(! strcmp(ls.at(i).nodeName().toStdString().c_str(), DIR_EXPQUES.toStdString().c_str()))
                {
                    settingXML.dir_exportQues = ls.at(i).toElement().text();
                }
            }
        }
        setting = setting.nextSiblingElement();
    }
    return settingXML;
}

QList<stQuestion> CXMLParser::parseQuesLibXMLFile(const QString &filePath)
{
    QList <stQuestion> quesList;
    // 打开或创建文件
    // 检验是否正常打开
    QFile file(filePath);
    if (!file.open(QFile::ReadOnly))
    {
        qDebug() << "file.open(QFile::ReadOnly)";
        // 打开文件失s败。
        return quesList;
    }

    QDomDocument doc;

    // 如果解析失败
    if (!doc.setContent(&file))
    {
        qDebug() << "doc.setContent(&file)";
        file.close();
        return quesList;
    }
    file.close();


    // 开始正常解析
    // 返回根节点(niso)
    QDomElement root = doc.documentElement();
    QDomNode node = root.firstChild();

    while (! node.isNull())
    {
        if (node.isElement())
        {

            QDomElement question = node.toElement();
            QDomNodeList ls = question.childNodes();

            stQuestion ques;
            for (int i = 0; i < ls.size(); i++)
            {
                if(0 == strcmp(ls.at(i).nodeName().toStdString().c_str(), QUES_PROTECTIONPOSITION.toStdString().c_str()))
                {
                    ques.protectionPosition = ls.at(i).toElement().text();

                }
                else if(0 == strcmp(ls.at(i).nodeName().toStdString().c_str(), QUES_DIFFICULTY.toStdString().c_str()))
                {
                    ques.difficulty = ls.at(i).toElement().text();

                }
                else if(0 == strcmp(ls.at(i).nodeName().toStdString().c_str(), QUES_INNERNUMBER.toStdString().c_str()))
                {
                    ques.innerNumber = ls.at(i).toElement().text();

                }
                else if(0 == strcmp(ls.at(i).nodeName().toStdString().c_str(), QUES_FILEMD5.toStdString().c_str()))
                {
                    ques.fileMd5 = ls.at(i).toElement().text();

                }
                else if(0 == strcmp(ls.at(i).nodeName().toStdString().c_str(), QUES_FLAG.toStdString().c_str()))
                {
                    ques.flag = ls.at(i).toElement().text();

                }
                else if(0 == strcmp(ls.at(i).nodeName().toStdString().c_str(), QUES_KNOWLEDGEPOINTS.toStdString().c_str()))
                {
                    ques.knowledgePoints = ls.at(i).toElement().text();

                }
                else if(0 == strcmp(ls.at(i).nodeName().toStdString().c_str(), QUES_FROMWHERE.toStdString().c_str()))
                {
                    ques.fromWhere = ls.at(i).toElement().text();

                }
            }
            quesList.push_back(ques);

            node = node.nextSiblingElement();
        }
    }
    return quesList;
}

bool CXMLParser::reWriteSettingFile(stSetting &setting, QString str_savePath)
{
    QFile fp;
    QDir(dir);
    fp.setFileName(str_savePath);                       //为fp指定包含路径的文件名
    if(fp.exists())                                     //若存在，读取
    {
        fp.remove();
    }

    fp.open(QIODevice::ReadWrite|QIODevice::Text);      // 不存在就会新建

    fp.write("<setting>\r\n");
    // 基础题库目录
    fp.write(("    <" + DIR_BASEQUESLIB + ">").toStdString().c_str());
    fp.write(setting.dir_baseQuesLib.toStdString().c_str());
    fp.write(("</" + DIR_BASEQUESLIB + ">").toStdString().c_str());
    fp.write("\r\n");

    // 导出题目的目录
    fp.write(("    <" + DIR_EXPQUES + ">").toStdString().c_str());
    fp.write(setting.dir_exportQues.toStdString().c_str());
    fp.write(("</" + DIR_EXPQUES + ">").toStdString().c_str());
    fp.write("\r\n");

    fp.write("</setting>");
    fp.write("\r\n");

    fp.close();
    return true;
}

// 将数据库中的题目信息导出为.xml文件
int CXMLParser::writeQuesSQLite2File(const stQuestion *quesBuffer, const int quesSize, const QString savedFilePath)
{
    QString space4 = "    ";
    QString space8 = "        ";
    QFile f_saved(savedFilePath);
    if ( f_saved.open(QIODevice::WriteOnly | QIODevice::Text))
    {
        f_saved.write("<queslib>\r\n");

        //循环写入题目
        for (int i = 0; i < quesSize; i++)
        {
            f_saved.write((space4 + "<question>\r\n").toUtf8());

            // 检测是否有xml需要转义的字符
            f_saved.write((space8 + "<protectionPosition>"  + quesBuffer[i].protectionPosition                  + "</protectionPosition>\r\n"   ).toUtf8());
            f_saved.write((space8 + "<difficulty>"          + quesBuffer[i].difficulty                          + "</difficulty>\r\n"           ).toUtf8());
            f_saved.write((space8 + "<innerNumber>"         + quesBuffer[i].innerNumber                         + "</innerNumber>\r\n"          ).toUtf8());
            f_saved.write((space8 + "<fileMd5>"             + quesBuffer[i].fileMd5                             + "</fileMd5>\r\n"              ).toUtf8());
            f_saved.write((space8 + "<flag>"                + swapEscapeChar(quesBuffer[i].flag)                + "</flag>\r\n"                 ).toUtf8());
            f_saved.write((space8 + "<knowledgePoints>"     + quesBuffer[i].knowledgePoints                     + "</knowledgePoints>\r\n"      ).toUtf8());
            f_saved.write((space8 + "<fromWhere>"           + swapEscapeChar(quesBuffer[i].fromWhere)           + "</fromWhere>\r\n"            ).toUtf8());

            f_saved.write((space4 + "</question>\r\n").toUtf8());
        }

        f_saved.write("</queslib>");
    }
    else
    {
#ifdef _N_Debug_
        qDebug() << L8BStr("【CXMLParser::writeQuesSQLite2File】打开文件") << savedFilePath << L8BStr("失败。");
#endif
        return -1;
    }
    f_saved.close();
    return 0;
}
